// 储存 用户相关的数据

// token要被vuex管理!!!  1.方便获取; 2.token响应式的, 一旦变化, 所有组件都知道

import { reqLogin, reqGetProfile, reqGetBaseInfo } from '@/api/user'
import { resetRouter } from '@/router'
import { getToken, removeToken, setToken } from '@/utils/auth'

const state = {
  // token优先从cookie获取
  token: getToken() || '',
  userInfo: {}
}
const mutations = {
  setToken(state, newToken) {
    state.token = newToken

    // token存到cookie
    setToken(newToken)
  },

  // 清除token
  removeToken(state) {
    // 清了仓库
    state.token = ''

    // 清了本地
    removeToken()
  },

  setUserInfo(state, newUserInfo) {
    state.userInfo = newUserInfo
  },

  // 清除个人信息
  removeUserInfo(state) {
    state.userInfo = {}
  }
}
const actions = {
  // 1.async函数默认返回promise
  // 2.async函数返回的promise 的值  由函数内部的return决定

  // 封装异步的操作 => 登录的异步操作
  async login(context, data) {
    const res = await reqLogin(data)
    // console.log(res)
    // res.data.data => token
    const newToken = res.data
    context.commit('setToken', newToken)
    // return undefined
    return res
  },

  // promise
  // login(context, data) {
  //   return new Promise((resolve, reject) => {
  //     // -----登录异步操作------
  //     reqLogin(data).then((res) => {
  //       // console.log(res, 98987)
  //       const newToken = res.data
  //       context.commit('setToken', newToken)
  //       // if()
  //       // console.log(res, 99999)
  //       resolve(res)
  //     }).catch((err) => {
  //       // 请求有失败的情况
  //       console.log(err)
  //       reject(err)
  //     })
  //   // -----登录异步操作------
  //   })
  // },

  // 这个写法完全等价 promise封装的写法
  // async函数 的返回值 默认就是一个promise, 他帮你做了一层封装
  async getUserProfile(context) {
    // 请求获取用户基本资料(不含头像)
    const { data: data1 } = await reqGetProfile()
    // console.log(data, 8989)
    // 用于获取用户基本资料(带头像)
    const { data: data2 } = await reqGetBaseInfo(data1.userId)

    // 合并所有的信息, 完整的信息存入仓库中, return完整信息
    const resObj = {
      ...data1,
      ...data2
    }

    // console.log(data2, 9090)
    context.commit('setUserInfo', resObj)
    //  async函数中 return xxx 相当于 resolve(xxx)
    // resolve(res)
    return resObj
  },

  // 退出登录(提交2个mutation)
  // action => 封装异步操作  也可以放同步的代码
  logout({ commit }) {
    // 1.移除token
    commit('removeToken')
    // 2.移除个人信息
    commit('removeUserInfo')

    // 官方提供的一个用于重置路由的函数
    // 3.重置路由
    resetRouter()

    // 4.同步一下vuex中的routes(优化)
    // 跨模块提交mutation/action 必须提供第三个参数 { root: true }
    // 1.先回到大仓库 2.在大仓库中找permission/setRoutes
    commit('permission/setRoutes', [], { root: true })

    // 5.清除主题色 => 跨模块
    commit('settings/resetTheme', null, { root: true })
  }

  // 请求是异步的
  // getUserProfile(context) {
  //   return new Promise((resolve, reject) => {
  //     // promise => 异步操作的容器
  //     // ---------异步操作的整体-------
  //     reqGetProfile().then((res) => {
  //       // console.log(res, 4590)
  //       context.commit('setUserInfo', res.data)
  //       resolve(res)
  //     }).catch((err) => {
  //       reject(err)
  //     })
  //     // ---------异步操作的整体-------
  //   })
  // }
}
const getters = {}

export default {
  // 开启命名空间  => 先找模块, 再找方法
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}
